home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Documentation / develop / develop Issue 7 / develop 7 code / QuickTime / SimpleInMovies / SimpleInWindows.c < prev   
Encoding:
C/C++ Source or Header  |  1992-10-15  |  13.1 KB  |  421 lines  |  [TEXT/MPS ]

  1. /*     
  2. SimpleInMovies
  3.  
  4. Sample programs demonstrating how to open and display
  5. QuickTime™ Movies.
  6.  
  7. SimpleInWindows.c file contains the code for the routines 
  8. having to do with creating closing a maintaining movie windows.
  9.  
  10. Guillermo A. Ortiz
  11. Macintosh Developer Technical Support
  12.  
  13. 08/07/91 Created the file to move in the window calls. Also added code to save
  14. the movie on closing if changes have been made.
  15.  
  16. 08/22/91 -- Added the code to accomodate the fact that the bounds for the controller now enclose the whole movie.
  17. 11/19/91 -- Fixed movie saving code to save correctly after saving as...
  18. 11/21/91 -- Finished the flattening code including the progress stuff.
  19.  
  20. 10/08/92 -- Added code to check/save the LOOP atom in the user data.
  21. 10/09/92 -- Added code to check/save the WLOC atom used to store the last position of the movie
  22. */
  23.  
  24. #include <SimpleInMovie.h>
  25.  
  26. extern Component movieControllerComponent;
  27. extern long gFlattenMovies;
  28.  
  29. /* ************************************************************************* */
  30. /* Procedures that handle window stuff */
  31.  
  32. Boolean CreateOneWindow(Movie, StandardFileReply, short, short);
  33. Boolean IsAppWindow(WindowPtr);
  34. Boolean    DisposeAllWindows(void);
  35. Boolean    DisposeOneWindow(WindowPtr, short);
  36. Boolean SaveMovie( DocRecHandle, short);
  37. Boolean DoSave(short);
  38. OSErr PutMovieToFile(DocRecHandle, Boolean);
  39.  
  40. extern DialogPtr GetCenteredDialog(short, WindowPtr, WindowPtr);
  41. extern void OutlineDialogItem(DialogPtr, short);
  42. extern pascal Boolean    keyEquivFilter(DialogPtr, EventRecord *, short *);
  43. extern Boolean DisplayPutFile(StandardFileReply *);
  44. extern Rect    CenterWindow(WindowPtr, WindowPtr);
  45. extern OSErr FixMovieWindow(WindowPtr window);
  46. extern short GetFileLoopState(DocRecHandle DocHandle);
  47. extern void SetLoopState(DocRecHandle wHndl);
  48. extern short GetCurrentLoopState(DocRecHandle wHndl);
  49. extern void UpdateLoopStateInfo(DocRecHandle wHndl);
  50. extern void FixWindowPosition(WindowPtr w,DocRecHandle wHndl);
  51. extern Boolean WPositionChanged(WindowPtr w,DocRecHandle DocHandle);
  52. extern void UpdateWindowPos(void);
  53.  
  54. extern short gUntitledCount;
  55.  
  56. /* opens a window for the movie and the record that keeps the movie playing
  57.    in the window as well as the instance for the player */
  58. Boolean CreateOneWindow(moov, fileInfo, fileResNum, moovResID)
  59. Movie moov;
  60. StandardFileReply fileInfo;
  61. short fileResNum;
  62. {
  63. WindowPtr        myWindow;
  64. Rect            moovBox;
  65. DocRecHandle    DocHandle;
  66. MovieController localController;
  67. Point where;
  68. OSErr err;
  69. Boolean emptyBox = false;
  70.  
  71. /*     Get our display window.
  72. */
  73.     myWindow = GetNewCWindow(windowID, nil, (WindowPtr) -1); 
  74.     
  75.     if ( myWindow && (DocHandle = (DocRecHandle)NewHandle(sizeof(DocRec))) ) {     /* get storage for            */
  76.       (*DocHandle)->wMovie = moov;                    /* movie                    */
  77.       (*DocHandle)->wFileInfo.sfr = fileInfo;            /* file                        */
  78.       (*DocHandle)->wFileInfo.resFile = fileResNum;
  79.       (*DocHandle)->wFileInfo.moovID = moovResID;
  80.        (*DocHandle)->loopState = noLoop; /* default */
  81.       
  82.        if ( localController = OpenComponent((Component)movieControllerComponent) ) { /* and component    */
  83.         (*DocHandle)->wPlayer = localController;    /* OpenComponent can move memory so it may not a good idea to dereference the handle in the same line */
  84.         SetWRefCon(myWindow, (long)DocHandle);
  85.         
  86.         /* now size window adding some space at the bottom for controller */
  87.         GetMovieBox(moov,&moovBox); /* Use the movie box to resize window */
  88.         
  89.         where.h = moovBox.left;
  90.         where.v = moovBox.top;
  91.  
  92.         if (err = MCNewAttachedController((*DocHandle)->wPlayer, moov, myWindow, where) )
  93.           DebugStr("\pError at PTNewAttachedController");
  94.                   
  95.         /* now we resize the window according to the controller settings and the
  96.            dimensions of the movie.
  97.         */
  98.         FixMovieWindow(myWindow);
  99.         
  100.         SetWTitle(myWindow,fileInfo.sfFile.name);
  101.             
  102.  
  103.         SetPort(myWindow);
  104.         
  105.         /* Before we play the movie check the state of looping an set it accordingly */
  106.         
  107.         if (fileResNum != kNoFileOpen) { /* the movie is not brand new */
  108.           (*DocHandle)->loopState = GetFileLoopState(DocHandle);
  109.           if ((*DocHandle)->loopState)
  110.             SetLoopState(DocHandle);
  111.         /* since we are here we can position the window according to the WLOC atom */
  112.           FixWindowPosition(myWindow, DocHandle);
  113.  
  114.         }
  115.         
  116.         ShowWindow(myWindow);
  117.         SelectWindow(myWindow);
  118.         
  119.         if (err = MCDoAction((*DocHandle)->wPlayer, mcActionPlay, (Ptr)0x00010000) )
  120.           DebugStr("\pError at MCGetControllerBoundsRect");
  121.  
  122.         return true;
  123.       }
  124.     }
  125.     /* something failed so we have to get rid of the window */
  126.     DisposeWindow(myWindow);
  127.     return(false);
  128. }
  129.  
  130. /* returns true if all windows have been closed */
  131. Boolean    DisposeAllWindows(void)
  132. {
  133.     WindowPtr    window;
  134.     
  135.     while (window = *(WindowPtr *)WindowList) {
  136.  
  137.         /* While we have a front window, try closing it. */
  138.  
  139.         if (!DisposeOneWindow(window, quitCommand)) return(false);
  140.     }
  141.  
  142.     return(true);
  143. }
  144.  
  145.  
  146. /* Closes one window */
  147.  
  148. Boolean    DisposeOneWindow(window, command)
  149. WindowPtr window;
  150. short command;
  151. {
  152.     DocRecHandle    wHndl;
  153.  
  154.     if (IsAppWindow(window)) {
  155.         if (wHndl = (DocRecHandle)GetWRefCon(window)) {     /* Get the storage handle */
  156.           if (SaveMovie(wHndl, command)   )
  157.             return (false);     /* who knows the user hit cancel maybe */
  158.  
  159. /*****     MCRemoveMovie goes away.
  160.           MCRemoveMovie((*wHndl)->wPlayer);
  161. */
  162.           CloseComponent((*wHndl)->wPlayer);            /* and player instance        */
  163.           DisposeMovie((*wHndl)->wMovie);                /* and get rid of movie        */
  164.           if ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum != kInvalVRefNum) {
  165.             if (CloseMovieFile((*wHndl)->wFileInfo.resFile) )/* file open, close it        */
  166.               DebugStr("\pCloseMovieFile failed in DisposeOneWindow"); 
  167.           }
  168.           DisposHandle((Handle)wHndl);                    /* and finally the handle    */
  169.         }
  170.     }
  171.     DisposeWindow(window);
  172.     return(true);
  173. }
  174.  
  175. Boolean IsAppWindow(window)
  176. WindowPtr window;
  177.     if (window)
  178.        return (((WindowPeek)window)->windowKind >= userKind);
  179.     else
  180.       return false;
  181. }
  182. /* *************************************************************** */
  183.  
  184. /* checks that there is a movie associated with the front most window
  185.    and tries to save it; this is used when the save or save as commands
  186.    are executed.
  187.    
  188. */
  189. Boolean DoSave(command)
  190. short command;
  191. {
  192. WindowPtr window;
  193. DocRecHandle wHndl;
  194. short volume;
  195.  
  196.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  197.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  198.         if (WPositionChanged(window, wHndl) ) { /* dirty the movie to save the position of the window */
  199.           volume = GetMoviePreferredVolume((*wHndl)->wMovie);
  200.           SetMoviePreferredVolume((*wHndl)->wMovie, volume+1);
  201.           SetMoviePreferredVolume((*wHndl)->wMovie, volume);
  202.         }
  203.         return SaveMovie(wHndl, command);
  204.       }
  205.     }
  206. }
  207.  
  208. /* The progress proc lets the user know what is going on while a FlattenMovie call
  209.    is being done.
  210.    Not from MacShell.
  211. */
  212. pascal OSErr flattenProgressProc(Movie m, short message, short operation, Fixed percent, long refCon)
  213. {
  214. #pragma unused (m)
  215.  
  216. WindowPtr    pDialog;
  217. Fixed        percentFix = 0x00640000;  /* hundred in fixed */
  218. short        percentShort;
  219. Rect        windRect,
  220.             progressRect= {100,20,120,200};
  221. GrafPtr        oldPort;
  222.  
  223.     if (operation != progressOpFlatten)    /* This should only be called for flatten */
  224.       return featureUnsupported;            
  225.     else                                            /* OK this I know about                            */
  226.       switch (message) {
  227.         case movieProgressOpen:
  228.           SetRect(&windRect,20,20,240,200);
  229.           pDialog = NewCWindow(nil,&windRect,"",false, dBoxProc, (WindowPtr)-1L,true,0);
  230.           CenterWindow(pDialog, nil);
  231.           if (pDialog) {
  232.               GetPort(&oldPort);
  233.               ShowWindow(pDialog);
  234.             SetPort(pDialog);
  235.             MoveTo(30,50);
  236.             DrawString("\pFlattening in progress …");
  237.             FrameRect(&progressRect);
  238.               *(WindowPtr *)refCon = pDialog; 
  239.             SetPort(oldPort);
  240.               return noErr;
  241.           }
  242.         break;
  243.         case movieProgressUpdatePercent:
  244.           GetPort(&oldPort);
  245.           SetPort(*(WindowPtr *)refCon);
  246.           percentFix = FixMul(percent, percentFix);
  247.             percentShort = FixRound(percentFix);
  248.           FrameRect(&progressRect);
  249.           InsetRect(&progressRect,2,2);
  250.           progressRect.right = progressRect.left+((progressRect.right - progressRect.left) * percentShort/100);
  251.           PaintRect(&progressRect);
  252.           SetPort(oldPort);                         
  253.           return noErr;
  254.         break;
  255.         case movieProgressClose:
  256.           DisposeWindow(*(WindowPtr *)refCon);
  257.           return noErr;
  258.         break;
  259.       }
  260. }
  261.  
  262.  
  263. /* The next procedures come from the DTS sample MacShell, check it out for more details or
  264.    better comments.    Note though that I have modified the code to accomodate the immediate
  265.    needs, don't blame MacShell.                                    */
  266.  
  267.  
  268. /* checks is the movie has to be saved and depending on the command that
  269.    originated the requests saves the movie.
  270. */   
  271.    
  272. Boolean SaveMovie( wHndl, command)
  273. DocRecHandle wHndl;
  274. short command;
  275. {
  276.     Str255                closeOrQuit;
  277.     short                item;
  278.     StandardFileReply    reply;
  279.     OSErr                err;
  280.     DialogPtr            saveDialog;
  281.  
  282.     if (command != saveMovieAs) {                        /* If regular save... */
  283.         if (!HasMovieChanged((*wHndl)->wMovie))    {        /* If movie clean...   */
  284.           /*except that looping could have changed. */
  285.           if ( (*wHndl)->loopState == GetCurrentLoopState(wHndl) )
  286.               return(noErr);                                /* Consider it saved. */
  287.         }
  288.     }
  289.  
  290.     if ((command == closeMovie) || (command == quitCommand)) {
  291.         /* If implicit save... */
  292.  
  293.         GetIndString(closeOrQuit, rMiscStrings,
  294.                      (command == closeMovie) ? sClosing : sQuitting);
  295.         ParamText((*wHndl)->wFileInfo.sfr.sfFile.name, closeOrQuit, nil, nil);
  296.  
  297.         saveDialog = GetCenteredDialog(rYesNoCancel, nil, (WindowPtr)-1L);
  298.  
  299.         if (saveDialog) {
  300.             OutlineDialogItem(saveDialog, kSaveYes);
  301.             ModalDialog((ModalFilterProcPtr)keyEquivFilter, &item);
  302.             DisposDialog(saveDialog);
  303.         }
  304.         else
  305.             item = kSaveYes;
  306.  
  307.         if (item != kSaveYes) {
  308.             err = noErr;
  309.             if (item == kSaveCanceled) err = userCanceledErr;
  310.             return(err);
  311.         }
  312.     }
  313.  
  314.     if (((command == saveMovieAs) ||
  315.         ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum == kInvalVRefNum) )) {
  316.         /* Prompt with SFGetFile if doing a Save As or have never saved before. */
  317.  
  318.         reply = (*wHndl)->wFileInfo.sfr;
  319.         
  320.         if (!DisplayPutFile(&(reply)))
  321.             return(userCanceledErr);
  322.                 /* User canceled the save. */
  323.  
  324.         if ((*wHndl)->wFileInfo.sfr.sfFile.vRefNum != kInvalVRefNum) {
  325.             if (err = CloseMovieFile((*wHndl)->wFileInfo.resFile) )
  326.               DebugStr("\pCloseMovieFile failed in SaveMovie"); 
  327.                 /* Close the old file.  Don't respond to any error here because
  328.                 ** the user may be trying to do a save-as because their old file
  329.                 ** is bad.  If we fail to close the old file, and then respond
  330.                 ** to the error, the user won't get the opportunity to save
  331.                 ** their document to a new file.
  332.                 */
  333.         }
  334.         SetWTitle(FrontWindow(),reply.sfFile.name);
  335.         (*wHndl)->wFileInfo.sfr = reply;
  336.         if ( err = PutMovieToFile(wHndl, true) ) {
  337.           reply.sfFile.vRefNum = kInvalVRefNum;
  338.           DebugStr("\pCouldn't create the new file for save as");
  339.         }
  340.     }
  341.     else /* saving into an existing file */
  342.       if (err = PutMovieToFile(wHndl, false) ) {
  343.         (*wHndl)->wFileInfo.sfr.sfFile.vRefNum = kInvalVRefNum;
  344.         return(err);
  345.       }
  346.     
  347.     ClearMovieChanged((*wHndl)->wMovie);
  348.     return(noErr);
  349. }
  350.  
  351.  
  352. OSErr PutMovieToFile(wHndl, newFile)
  353. DocRecHandle    wHndl;
  354. Boolean            newFile;
  355. {
  356. OSErr theErr;
  357. short    resFile, 
  358.         resID = 0; /* resource id = 0 tells the MovieToolbox to come up with a number */
  359. DialogPtr flattenDialog;     /* the progress proc stores here its dialog pointer */
  360.  
  361.     /* we are about to save the file this is a good time to update the loop state both
  362.        in memory and in the file.
  363.        
  364.     */
  365.     
  366.     UpdateLoopStateInfo(wHndl);
  367.     
  368.     UpdateWindowPos();
  369.     
  370.     resFile = CurResFile();
  371.     if (newFile) {
  372.       if ( gFlattenMovies) {
  373.       
  374.           /* Brackett Flatten movie with SetMovieProgress proc calls so that the user
  375.            gets to know what is going on if the flattening takes too long.
  376.            It is also important to lock the handle containing the movie reference,
  377.            FlattenMovie moves data around and since we are dereferencing the handle
  378.            the pointer we pass could end up pointing to garbage.
  379.         */
  380.         HLock((Handle)wHndl);
  381.         SetMovieProgressProc((*wHndl)->wMovie, flattenProgressProc, (long) &flattenDialog);
  382.  
  383.         FlattenMovie((*wHndl)->wMovie, 0 /* flags */, 
  384.                      &((*wHndl)->wFileInfo.sfr.sfFile), 'TVOD',0,
  385.                      createMovieFileDeleteCurFile /* createMovieFileFlags*/,
  386.                       &resID, nil /* resName */);
  387.  
  388.         HUnlock((Handle)wHndl);
  389.         if (theErr = GetMoviesError())
  390.           DebugStr("\pFlattenMovie failed");
  391.         else
  392.           (*wHndl)->wFileInfo.moovID = resID;        /* remember the moov resource id */
  393.  
  394.         SetMovieProgressProc((*wHndl)->wMovie, nil, 0); /* flattening is done remove proc */
  395.  
  396.         if (theErr = OpenMovieFile( &((*wHndl)->wFileInfo.sfr.sfFile),
  397.                                     &((*wHndl)->wFileInfo.resFile),fsRdWrPerm))
  398.           DebugStr("\pOpenMovieFile failed");
  399.       }
  400.       else /* do not flatten */
  401.         {
  402.           if ( !(theErr = CreateMovieFile(  &((*wHndl)->wFileInfo.sfr.sfFile), 'TVOD',0,createMovieFileDeleteCurFile, 
  403.                                      &((*wHndl)->wFileInfo.resFile), nil) )) {
  404.             if (theErr = AddMovieResource((*wHndl)->wMovie, (*wHndl)->wFileInfo.resFile, 
  405.                                         &resID, nil /* resName */) )
  406.               DebugStr("\pAddMovieResource failed in PutMovieToFile");
  407.             else
  408.              (*wHndl)->wFileInfo.moovID = resID;        /* remember the moov resource id */
  409.           }
  410.           else DebugStr("\pCreateMovieFile Failed in PutMovieToFile");
  411.         }
  412.     }
  413.     else 
  414.       if (theErr = UpdateMovieResource( (*wHndl)->wMovie, (*wHndl)->wFileInfo.resFile, 
  415.                                     (*wHndl)->wFileInfo.moovID, nil))
  416.         DebugStr("\pPutMovieToFile: UpdateMovieResource failed");
  417.  
  418.     UseResFile(resFile);
  419.     return (theErr);
  420. }